/*
 * AbstractElement.h
 *
 *  Created on: 2010-9-26
 *      Author: wenjian
 */

#ifndef ABSTRACTELEMENT_H_
#define ABSTRACTELEMENT_H_
#include "../commons.h"
#include "eventtypes.h"
#include "ddatatypes.h"
#include "VisibleSupport.h"
#include "ModifiedSupport.h"
#include "ModifiedEvent.h"
#include "MouseEvent.h"
#include "KeyEvent.h"
#include "CursorSupport.h"
#include "Cursor.h"
#include "EventSupport.h"
#include "SelectEvent.h"
#include "MoveSupport.h"
#include "PaintEvent.h"

namespace Ed {
  class AbstractLayer;
  class AbstractElements;


  class AbstractElement :
    public VisibleSupport,
    public ModifiedSupport,
    public EventSupport,
    public CursorSupport,
    public MoveSupport{

    friend class AbstractElements;
    friend class AbstractLayer;

    public:
      AbstractElement();
      virtual ~AbstractElement();


      /**
       * 返回x坐标
       */
      virtual inline real x() const{
        return _x;
      }
      /**
       * 返回y坐标
       */
      virtual inline real y() const{
        return _y;
      }

      /**
       * 返回元素宽度
       */
      virtual inline real width() const{
        return _w;
      }

      /**
       * 设置宽度
       */
      virtual void setWidth(real w){
        if(_w != w){
          _w = w;
          setModified(true);
        }
      }

      /**
       * 返回元素高度
       */
      virtual inline real height() const{
        return _h;
      }

      /**
       * 设置高度
       */
      virtual void setHeight(real h){
        if(_h != h){
          _h = h;
          setModified(true);
        }
      }

      /**
       * 设置新坐标
       */
      virtual void setCoordinate(real x, real y);

      /**
       * 增量移动到目标位置
       */
      virtual void moveBy(real dx, real dy);

      /**
       *设置Modified标记
       */
      virtual void setModified(bool b);

      /**
       * 构建路径
       */
      //virtual void createPath()=0;
      virtual void createPath(){
        createBoundRect();
      }

      /**
       * 创建包含元素所有可视内容的最大矩形区域
       */
      virtual void createBoundRect(){};

      /**
       * 重画与此元素相交的其它元素, 排除<code>excludeds</code>中的元素
       */
      //virtual void redrawIntersection(const std::vector<AbstractElement*>* excludeds=NULL)=0;
      virtual void redrawIntersection(const std::vector<AbstractElement*>* excludeds=NULL){};

      /**
       * 重画与此元素相交的元素, 包括相交元素和自己, 排除<code>excludeds</code>中的元素
       */
      //virtual void redrawAll(const std::vector<AbstractElement*>* excludeds=NULL)=0;
      virtual void redrawAll(const std::vector<AbstractElement*>* excludeds=NULL){};

      /**
       * 返回图层
       */
      virtual inline AbstractLayer* getLayer(){
        return layer;
      }

      /**
       * 设置图层
       */
      virtual inline void setLayer(AbstractLayer* l){
        layer = l;
      }

      /**
       * 检查重画标记
       */
      virtual inline bool isRedraw() const{
        return redrawFlag;
      }
      /**
       * 设置重画标记
       */
      virtual inline void setRedraw(bool b){
        redrawFlag = b;
      }

//      /**
//       * 检查是否与元素e相交
//       */
//      //virtual bool intersects(AbstractElement* e)=0;
//      virtual bool intersects(AbstractElement* e){
//        return false;
//      }

      /**
       * 检查是否与点(x, y)相交
       */
      //virtual bool intersects(real x, real y)=0;
      virtual bool intersects(real x, real y){
        return false;
      }


      /**
       * 检查鼠标是否正停在此元素上面
       */
      virtual inline bool mouseIsHovering(){
        return mouseHovering;
      }

      /**
       * 检查选中状态
       */
      virtual inline bool isSelected(){
        return selected;
      }

      /**
       * 设置选中状态, 参数fireEvent指示是否产生SelectEvent事件
       *
       */
      virtual void setSelected(bool b, bool fireEvent=true);

      /**
       * 设置焦点
       */
      virtual void setFocus();

      /**
       * 检查是否焦点层
       */
      virtual bool isFocus();

      /**
       * 设置是否响应事件
       */
      virtual void setEventEnabled(bool e){
        eventEnabled = e;
      }

      /**
       * 检查是否响应事件
       */
      virtual bool isEventEnabled(){
        return eventEnabled;
      }

      /**
       * 跟踪响应事件, 向元素传递鼠标、键盘或其它事件
       */
      virtual bool trackEvent(const Thk::Event* e);

    protected:
      /**
       * 处理鼠标事件
       */
      virtual bool handleMouseEvent(const MouseEvent* me);


      /**
       * 发送鼠标离开元素事件
       */
      virtual bool mouseLeave();

      /**
       * 发送鼠标进入元素事件
       */
      virtual bool mouseEnter();

    private:

      /**
       * 抛出绘制元素事件
       */
      void throwPaintEvent(){
        event(&paintEvent);
      }

    protected:
      AbstractLayer* layer;

      //x, y坐标, 宽度和高度
      real _x, _y, _w, _h;

      //仅重画自己标记
      bool redrawFlag;

//      //最大边界矩形
//      T_Rect* boundRect;

      //鼠标正在此元素上移动时，设置此标记
      bool mouseHovering;

      //定义鼠标移出事件
      MouseEvent mLeaveEvent;
      //定义鼠标移入事件
      MouseEvent mEnterEvent;

      //定义选择事件
      SelectEvent selectEvent;

      //选中标记
      bool selected;

      //定义改变被修改状态事件
      ModifiedEvent modifiedEvent;

      //是否能响应事件
      bool eventEnabled;

      //定义绘制元素事件
      PaintEvent paintEvent;

  };

}

#endif /* ABSTRACTELEMENT_H_ */
